﻿using System;
using RedirectManager.Interfaces;
using RedirectManager.Pipelines.HttpRequest;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Web.UI.Sheer;

namespace RedirectManager.Shell.Framework.Pipelines
{
    using RedirectManager.Pipelines.PublishItem;
    using System.Text.RegularExpressions;

    [Serializable]
    public class AddRedirect
    {
        private ILookupProvider provider;

        #region methods

        public AddRedirect()
        {
            this.provider = Redirector.Provider;
        }

        public void CheckPermissions(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (SheerResponse.CheckModified())
            {
                string str = args.Parameters["id"];
                Item item = PipelineContextDatabase(args).GetItem(str);
                if (item != null)
                {
                    if (!item.Access.CanWrite())
                    {
                        SheerResponse.Alert(Translate.Text("You do not have permission create redirect item \"{0}\".", new object[] { item.DisplayName }), new string[0]);
                        args.AbortPipeline();
                    }
                }
                else
                {
                    SheerResponse.Alert("Item not found.", new string[0]);
                    args.AbortPipeline();
                }
            }
        }

        public void GetName(ClientPipelineArgs args)
        {
            if (!args.IsPostBack)
            {
                // Can't use in build regex checking overload as is doesn't want to work with our regex that contains a mode modifier 
                Context.ClientPage.ClientResponse.Input("Enter the url path to be redirected to this item i.e. <b>/promo/offers</b> :", "/"); //, Config.UrlPathValidationExpression, "'$Input' is not a valid url path.", 9999);
                args.WaitForPostBack();
            }
            else if (args.HasResult)
            {
                if (!Regex.IsMatch(args.Result, Config.UrlPathValidationExpression))
                {
                    Context.ClientPage.ClientResponse.Alert("Url path contains illegal characters");
                    args.AbortPipeline();
                }

                args.Parameters["urlPathInput"] = args.Result;
            }
            else
            {
                args.AbortPipeline();
            }
        }

        public void CheckDuplicate(ClientPipelineArgs args)
        {
            if (Config.CheckDuplicateUrlOnCreate)
            {
                if (this.provider.Exists(args.Parameters["urlPathInput"]))
                {
                    SheerResponse.Alert(string.Format("Error: An existing redirect exists for the supplied url path '{0}'", args.Parameters["urlPathInput"]), new string[0]);
                    args.AbortPipeline();
                }
            }
        }

        public void Execute(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");

            string targetId = args.Parameters["id"];
            string requestPath = args.Parameters["urlPathInput"];

            Log.Audit(this, "Redirect Manager: adding redirect item for url path : '{0}'", requestPath);
            this.provider.Create(args.Parameters["urlPathInput"], targetId, false);
            Context.ClientPage.ClientResponse.Alert("Added");
            var refresh = string.Format("item:load(id={0})", targetId);
            Context.ClientPage.ClientResponse.Timer(refresh, 2);
        }

        private static Database PipelineContextDatabase(ClientPipelineArgs args)
        {
            Database database = Factory.GetDatabase(args.Parameters["database"]);
            Assert.IsNotNull(database, args.Parameters["database"]);
            return database;
        }

        #endregion
    }
}
